package winOrDie.graphics.maps;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import winOrDie.graphics.maps.Map_Cell.Map_Cell_Type;

/**
 * This public class defines different methods for load and save {@link Map_Cell} data
 */
public final class Map_Cell_Editor 
{
	/**
	 * This public static class defines the names of {@link Map_Cell} XML elements.
	 */
	public static class XML_ELEMENTS_Map_Cell
	{
		public static final String Element_Map_Cell = "Map_Cell";
		public static final String Attribute_Type = "Type";
		public static final String Attribute_Image = "Image";
	}
	
	
	/**
	 * This public static class defines the codes for the different {@link Map_Cell} types
	 */
	public static class XML_CODES_Map_Cell_Type
	{
		public static final String Corridor = "Corridor";
		public static final String Wall = "Wall";
		public static final String Pirates_Room = "Pirates_Room";
		public static final String Tower = "Tower";
		public static final String Tower_Door = "Tower_Door";
		public static final String Exit = "Exit";
	}

	/**
	 * This public static method returns the {@link String} xml code for the type of {@link Map_Cell} object passed as parameter
	 * @param mapCell
	 * @return {@link String}
	 * @throws Exception
	 */
	public static String get_Map_Cell_Type_Code(Map_Cell mapCell) throws Exception
	{
		switch (mapCell.getType()) 
		{
		case Map_Cell_Type.Corridor:
			return XML_CODES_Map_Cell_Type.Corridor;
		case Map_Cell_Type.Wall:
			return XML_CODES_Map_Cell_Type.Wall;
		case Map_Cell_Type.Pirates_Room:
			return XML_CODES_Map_Cell_Type.Pirates_Room;
		case Map_Cell_Type.Tower:
			return XML_CODES_Map_Cell_Type.Tower;
		case Map_Cell_Type.Tower_Door:
			return XML_CODES_Map_Cell_Type.Tower_Door;
		case Map_Cell_Type.Exit:
			return XML_CODES_Map_Cell_Type.Exit;
		default:
			Exception exception = new Exception("Unknown map cell type " + mapCell.getType());
			throw exception;
		}
	}
	
	/**
	 * This public static method returns the {@link Map_Cell_Type} of {@link XML_CODES_Map_Cell_Type} {@link String} passed as parameter
	 * @param map_Cell_Type_Code
	 * @return int
	 * @throws Exception
	 */
	public static int get_Map_Cell_Type_From_Code(String map_Cell_Type_Code) throws Exception
	{
		if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Corridor))
		{
			return Map_Cell_Type.Corridor;
		}
		else if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Pirates_Room))
		{
			return Map_Cell_Type.Pirates_Room;
		}
		else if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Tower))
		{
			return Map_Cell_Type.Tower;
		}
		else if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Tower_Door))
		{
			return Map_Cell_Type.Tower_Door;
		}
		else if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Wall))
		{
			return Map_Cell_Type.Wall;
		}
		else if (map_Cell_Type_Code.equals(XML_CODES_Map_Cell_Type.Exit))
		{
			return Map_Cell_Type.Exit;
		}
		else
		{
			Exception exception = new Exception("The map cell type code " + map_Cell_Type_Code + " is unknown.");
			throw exception;
		}
	}
	

	/**
	 * This public static method returns a {@link Element} object with the data of {@link Map_Cell} object passed as parameter. 
	 * The {@link Element} is created from {@link Document} object passed as parameter 
	 * @param mapCell
	 * @param document
	 * @return {@link Element}
	 * @throws Exception
	 */
	public static Element get_Element_From_Map_Cell(
			Map_Cell mapCell,
			Document document
			) throws Exception
	{
		Element element_Map_Cell = document.createElement(XML_ELEMENTS_Map_Cell.Element_Map_Cell);
		
		element_Map_Cell.setAttribute(
				XML_ELEMENTS_Map_Cell.Attribute_Type, 
				get_Map_Cell_Type_Code(mapCell)
			);
		
		element_Map_Cell.setAttribute(
				XML_ELEMENTS_Map_Cell.Attribute_Image, 
				mapCell.getImage()
			);
		
		return element_Map_Cell;
		
	}
	
	
	/**
	 * This public static method loads the data of {@link Element} passed as parameter into {@link Map_Cell} object passed as parameter
	 * @param mapCell
	 * @param element
	 * @throws Exception
	 */
	public static void load_Map_Cell_From_Element(Map_Cell mapCell, Element element) throws Exception
	{
		if (!element.getNodeName().equals(XML_ELEMENTS_Map_Cell.Element_Map_Cell))
		{
			Exception exception = new Exception("The element is not a Map_Cell element.");
			throw exception;
		}

		mapCell.setType(
				get_Map_Cell_Type_From_Code(
						element.getAttribute(XML_ELEMENTS_Map_Cell.Attribute_Type)
					)
			);
		
		mapCell.setImage(
				element.getAttribute(XML_ELEMENTS_Map_Cell.Attribute_Image)
			);
		
		
	}
	
}
